#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkInterface>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint);
    setFixedSize(size());

    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    foreach (const QNetworkInterface& interface, interfaces) {
        QList<QNetworkAddressEntry> entries = interface.addressEntries();
        if (interface.flags() & QNetworkInterface::IsUp) {
            foreach (const QNetworkAddressEntry& entry, entries) {
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                    ui->localIpComboBox->addItem(entry.ip().toString());
                }
            }
        }
    }

    statisticsTimer = new QTimer(this);
    statisticsTimer->setInterval(1000);
    connect(statisticsTimer, &QTimer::timeout, this, &MainWindow::on_statisticsTimerDone);

    trayIcon = new QSystemTrayIcon(this);
    connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::on_trayIconActived);
    trayIcon->setIcon(QIcon(":/link.ico"));
    trayIcon->setToolTip("TCP Port remap 未启动");
    trayIcon->setVisible(true);

    trayMenu = new QMenu(this);
    quitAction = trayMenu->addAction("退出");
    connect(quitAction, &QAction::triggered, [](){
        qApp->quit();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_newConnection()
{
    QTcpSocket *client = server->nextPendingConnection();

    QString serverIp = ui->serverIpLineEdit->text();
    unsigned short serverPort = ui->serverPortLineEdit->text().toUShort();
    TcpForward *forward = new TcpForward(client, serverIp, serverPort);
    forwards.append(forward);
    connect(forward, &TcpForward::disconnect, this, &MainWindow::on_forwardDestroyed);
    connect(forward, &TcpForward::uploadBytes, this, &MainWindow::on_upload);
    connect(forward, &TcpForward::downloadBytes, this, &MainWindow::on_download);

    ui->clientNumLabel->setText(QString::number(forwards.count()));
}

void MainWindow::on_forwardDestroyed(TcpForward *forward)
{
    forwards.removeOne(forward);
    ui->clientNumLabel->setText(QString::number(forwards.count()));
}

void MainWindow::on_startRadioButton_toggled(bool checked)
{
    if (checked) {
        server = new QTcpServer(this);
        connect(server, &QTcpServer::newConnection, this, &MainWindow::on_newConnection);
        unsigned short clientsPort = ui->remapPortLineEdit->text().toUShort();
        bool ret = server->listen(QHostAddress::Any, clientsPort);
        if (ret) {
            statisticsTimer->start();
            trayIcon->setToolTip("TCP Port remap 已启动");
            trayIcon->showMessage("TCP Port Remap", "已启动");
        }
    } else {
        statisticsTimer->stop();
        uploadCount = 0;
        downloadCount = 0;
        on_statisticsTimerDone();

        foreach (TcpForward *forward, forwards) {
            delete forward;
        }
        forwards.clear();

        server->close();
        delete server;
        trayIcon->setToolTip("TCP Port remap 未启动");
    }
}

void MainWindow::on_localIpComboBox_currentTextChanged(const QString &arg1)
{
    QString httpCmd = QString("export http_proxy=%1:%2").arg(arg1, ui->remapPortLineEdit->text());
    QString httpsCmd =  QString("export https_proxy=%1:%2").arg(arg1, ui->remapPortLineEdit->text());
    ui->cmdTextBrowser->clear();
    ui->cmdTextBrowser->append(httpCmd);
    ui->cmdTextBrowser->append(httpsCmd);
    ui->cmdTextBrowser->append("\n");
}

void MainWindow::on_upload(int num)
{
    uploadCount += num;
}

void MainWindow::on_download(int num)
{
    downloadCount += num;
}

void MainWindow::on_statisticsTimerDone()
{
    if (uploadCount >= 1024*1024) { // MB
        ui->upSpeedLabel->setText(QString::number(uploadCount/1024.0/1024, 'g', 4) + " MBps");
    } else if (uploadCount >= 1024) { // KB
        ui->upSpeedLabel->setText(QString::number(uploadCount/1024.0, 'g', 4) + " KBps");
    } else {
        ui->upSpeedLabel->setText(QString::number(uploadCount) + " Bps");
    }
    uploadCount = 0;

    if (downloadCount >= 1024*1024) { // MB
        ui->downSpeedLabel->setText(QString::number(downloadCount/1024.0/1024, 'g', 4) + " MBps");
    } else if (downloadCount >= 1024) { // KB
        ui->downSpeedLabel->setText(QString::number(downloadCount/1024.0, 'g', 4) + " KBps");
    } else {
        ui->downSpeedLabel->setText(QString::number(downloadCount) + " Bps");
    }
    downloadCount = 0;
}

void MainWindow::on_trayIconActived(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
        case QSystemTrayIcon::Context : {
            QPoint globalPos = QCursor::pos();
            trayMenu->exec(globalPos);
        } break;
        case QSystemTrayIcon::Trigger : {
            setHidden(!isHidden());
            if (!isHidden()) {
                showNormal();
                raise();
                activateWindow();
            }
        } break;
        default: break;
    }
}

void MainWindow::hideEvent(QHideEvent *event)
{
    hide();
    event->ignore();
}
